package com.fjut.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjut.client.userInfo.UserInfoFeignClient;
import com.fjut.mapper.CouponInfoMapper;
import com.fjut.model.activity.CouponInfo;
import com.fjut.model.activity.CouponUse;
import com.fjut.model.user.UserInfo;
import com.fjut.service.CouponInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjut.service.CouponUseService;
import com.fjut.utils.AuthContextHolder;
import com.fjut.utils.JwtHelper;
import com.fjut.vo.activity.CouponInfoVo;
import com.fjut.vo.activity.CouponUseQueryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

import static com.fjut.dateBase.CouponUseField.*;
import static com.fjut.dateBase.UserInfoField.USER_ID;

/**
 * <p>
 * 优惠券信息 服务实现类
 * </p>
 *
 * @author DengTianxun
 * @since 2023-03-09
 */
@Service
public class CouponInfoServiceImpl extends ServiceImpl<CouponInfoMapper, CouponInfo> implements CouponInfoService {

    private static final String NICKNAME = "nickName";
    private static final String PHONE = "phone";
    @Autowired
    private CouponUseService couponUseService;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Override
    public IPage<CouponUse> getCouponUsedPageInfo(Page<CouponUse> usePage, CouponUseQueryVo couponUseQueryVo) {
        QueryWrapper<CouponUse> useQueryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(couponUseQueryVo.getCouponId())) {
            useQueryWrapper.eq(COUPON_ID, couponUseQueryVo.getCouponId());
        }
        if (!StringUtils.isEmpty(couponUseQueryVo.getCouponStatus())) {
            useQueryWrapper.eq(COUPON_STATUS, couponUseQueryVo.getCouponStatus());
        }
        if (!StringUtils.isEmpty(couponUseQueryVo.getGetTimeBegin())) {
            useQueryWrapper.ge(GET_TIME, couponUseQueryVo.getGetTimeBegin());
        }
        if (!StringUtils.isEmpty(couponUseQueryVo.getGetTimeEnd())) {
            useQueryWrapper.le(GET_TIME, couponUseQueryVo.getGetTimeEnd());
        }
        couponUseService.page(usePage, useQueryWrapper);
        List<CouponUse> couponUses = usePage.getRecords();
        couponUses.forEach(couponUse -> {
            this.getUserInfoById(couponUse);
        });
        return usePage;
    }

    @Override
    public Boolean updateCouponInfo(Long couponUseId, Long orderId) {
        CouponUse couponUse = new CouponUse();
        couponUse.setOrderId(orderId);
        couponUse.setId(couponUseId);
        couponUse.setCouponStatus("1");
        couponUse.setUpdateTime(new Date());
        return couponUseService.updateById(couponUse);
    }

    @Override
    public Map<String, Object> getCouponUnusedInfo() {
        Long userId = AuthContextHolder.getUserId();
        QueryWrapper<CouponUse> wrapper = new QueryWrapper<>();
        wrapper.eq(USER_ID, userId);
        List<CouponUse> useList = couponUseService.list(wrapper);
        List<CouponInfoVo> couponUseQueryVos = new ArrayList<>();
        List<CouponInfoVo> couponUnusedQueryVos = new ArrayList<>();
        useList.forEach(use -> {
            CouponInfoVo couponInfoVo = new CouponInfoVo();
            CouponInfo couponInfo = this.getById(use.getCouponId());
            couponInfoVo.setId(couponInfo.getId());
            couponInfoVo.setCouponUseId(use.getId());
            couponInfoVo.setAvailable(Integer.valueOf(use.getCouponStatus()));
            couponInfoVo.setName(couponInfo.getCouponName());
            couponInfoVo.setStartAt(couponInfo.getStartTime().getTime());
            couponInfoVo.setEndAt(couponInfo.getEndTime().getTime());
            couponInfoVo.setDescription(couponInfo.getRuleDesc());
            couponInfoVo.setValue(couponInfo.getAmount());
            couponInfoVo.setCondition(couponInfo.getConditionAmount());
            if (use.getCouponStatus().equals("0")) {
                couponUseQueryVos.add(couponInfoVo);
            } else {
                BeanUtils.copyProperties(use, couponInfoVo);
                couponUnusedQueryVos.add(couponInfoVo);
            }
        });
        Map<String, Object> map = new HashMap<>();
        map.put("ableCouponsList", couponUseQueryVos);
        map.put("disabledCouponsList", couponUnusedQueryVos);
        return map;
    }

    @Override
    public Boolean issueCoupons(Long id) {
        List<UserInfo> userInfoList = userInfoFeignClient.getAllUserInfo();
        userInfoList.forEach(userInfo -> {
            CouponInfo couponInfo = baseMapper.selectById(id);
            QueryWrapper<CouponUse> useQueryWrapper = new QueryWrapper<>();
            useQueryWrapper.eq(COUPON_ID, couponInfo.getId());
            useQueryWrapper.eq(USER_ID, userInfo.getId());
            CouponUse one = couponUseService.getOne(useQueryWrapper);
            if (one == null) {
                CouponUse couponUse = new CouponUse();
                couponUse.setCouponId(id);
                couponUse.setUserId(userInfo.getId());
                couponUse.setCouponStatus("0");
                couponUse.setGetTime(new Date());
                couponUse.setExpireTime(couponInfo.getExpireTime());
                couponUse.setCreateTime(new Date());
                couponUse.setUpdateTime(new Date());
                couponUseService.save(couponUse);
            }
        });
        return true;
    }

    private void getUserInfoById(CouponUse couponUse) {
        if (!StringUtils.isEmpty(couponUse.getUserId())) {
            UserInfo userInfo = userInfoFeignClient.getUserInfoById(couponUse.getUserId());
            if (userInfo != null) {
                couponUse.getParam().put(NICKNAME, userInfo.getNickName());
                couponUse.getParam().put(PHONE, userInfo.getPhone());
            }
        }
    }
}
